package cn.com.huzo.service.tech.impl;

import cn.com.huzo.model.entities.tech.MrpHeaderEntity;
import cn.com.huzo.repository.purchase.PoNoticeRepository;
import huzofw.model.entities.paginator.Paginator;
import cn.com.huzo.repository.tech.PieceYardageLinesProductColourRepository;
import cn.com.huzo.repository.trade.ProductionInstructionLinesRepository;
import huzofw.service.impl.GenericManagerImpl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.com.huzo.repository.tech.MrpHeaderRepository;
import cn.com.huzo.service.tech.MrpHeaderManager;
import cn.com.huzo.repository.tech.MrpLinesAssortmentRepository;
import cn.com.huzo.repository.tech.MrpLinesResultRepository;
import cn.com.huzo.repository.trade.ProductionInstructionLinesDestinationRepository;
import cn.com.huzo.repository.trade.ProductionInstructionLinesDestinationSchemaRepository;
import cn.com.huzo.repository.trade.ProductionInstructionLinesSuitSizeRepository;
import cn.com.huzo.repository.trade.ProductionInstructionLinesSuitStyleNoRepository;
import org.apache.commons.collections4.MapUtils;

/**
 * 物料需求计划管理服务对象类实现。
 *
 * @author 吴旭
 */
@Service("MrpHeaderManager")
public class MrpHeaderManagerImpl extends GenericManagerImpl<MrpHeaderEntity, Long>
        implements MrpHeaderManager {

    @Resource(name = "MrpHeaderRepository")
    private MrpHeaderRepository _dao;

    @Resource(name = "MrpLinesAssortmentRepository")
    private MrpLinesAssortmentRepository _dao_lines_assortment;

    @Resource(name = "MrpLinesResultRepository")
    private MrpLinesResultRepository _dao_lines_result;

    @Resource(name = "ProductionInstructionLinesRepository")
    private ProductionInstructionLinesRepository _dao_mo_lines;

    @Resource(name = "ProductionInstructionLinesDestinationSchemaRepository")
    private ProductionInstructionLinesDestinationSchemaRepository _dao_mo_lines_schedule;

    @Resource(name = "ProductionInstructionLinesSuitSizeRepository")
    private ProductionInstructionLinesSuitSizeRepository _dao_mo_lines_size;

    @Resource(name = "ProductionInstructionLinesDestinationRepository")
    private ProductionInstructionLinesDestinationRepository _dao_mo_lines_destination;

    @Resource(name = "PieceYardageLinesProductColourRepository")
    private PieceYardageLinesProductColourRepository _dao_lines_bom_product_colour;

    @Resource(name = "PoNoticeRepository")
    private PoNoticeRepository _dao_po_notice;

    @Resource(name = "ProductionInstructionLinesSuitStyleNoRepository")
    private ProductionInstructionLinesSuitStyleNoRepository _dao_mo_lines_styleno;

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Override
    @Transactional
    public Map<String, Object> fetchByHeaderId(Long headerId, Long currentUserId, Long workFlowId) throws Exception {
        Map<String, Object> _result = new HashMap();

        MrpHeaderEntity instance = _dao.fetchByKey(headerId, currentUserId, workFlowId);
        _result.put("HeaderEntity", instance);
        _result.put("ScheduleNode", _dao_mo_lines_schedule.fetchScheduleDateNode(instance.getMoHeaderId()));
        _result.put("DestinationNode", _dao_mo_lines_destination.fetchProductionInstructionLinesDestinationNode(instance.getMoHeaderId()));
        _result.put("MoLinesList", _dao_mo_lines.fetchLinesByHeaderIdAndStyleNo(instance.getMoHeaderId(), instance.getStyleNo()));
        // 取得搭配明细（计算用单耗明细）
        _result.put("AssortmentLinesList", _dao_lines_assortment.fetchByHeaderId(headerId));
        // 取得计算用单耗明细用成品色
        _result.put("ProductColourNode", _dao_lines_bom_product_colour.fetchByHeaderKey(instance.getBomHeaderId()));
        // 取得材料用量明细
        _result.put("MrpLinesList", _dao_lines_result.fetchByHeaderId(headerId));
        // 取得通知的采购担当
        _result.put("PurchasedByNameList", _dao_po_notice.fetchPurchasedByName(headerId, (short) 0));

        return _result;
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public Map<String, Object> fetchForPage(Map<String, Object> criterion) throws Exception {
        Map<String, Object> _result = new HashMap();

        Long offset = (long) (MapUtils.getInteger(criterion, "Limit") * (MapUtils.getInteger(criterion, "PageIndex") - 1));
        long total = _dao.fetchForCount(criterion);

        if (total > 0) {
            if (offset >= total) {
                offset = (total - MapUtils.getInteger(criterion, "Limit")) < 0 ? 0 : (total - MapUtils.getInteger(criterion, "Limit"));
            }
            criterion.put("Offset", offset);
            List<MrpHeaderEntity> itemList = _dao.fetchForPage(criterion);
            Paginator<MrpHeaderEntity> paginator = new Paginator<>(itemList, offset, MapUtils.getInteger(criterion, "Limit"), total);

            _result.put("TotalRecordCount", paginator.getTotal());
            _result.put("TotalPages", paginator.getTotalPages());
            _result.put("PageIndex", paginator.getPageIndex());
            _result.put("DataList", paginator.getItemList());
            _result.put("Success", true);
        } else {
            _result.put("Success", false);
        }

        return _result;
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public List<MrpHeaderEntity> fetchAll(Map<String, Object> criterion) throws Exception {
        return _dao.fetchAll(criterion);
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public Map<String, Object> add(MrpHeaderEntity instance) throws Exception {
        // 插入主记录
        Long key = _dao.insert(instance);

        if (key > 0) {
            if (_dao_lines_assortment.insertLinesForSyncBom(key, instance.getBomHeaderId(), instance.getUpdatedBy()) > 0) {
                // 初始化明细数据, 默认搭配类型设置为"9"即无搭配
                _dao_lines_assortment.batchAssort(key, instance.getMoHeaderId(), instance.getStyleNo(), (short) 9);
                // 更新类型 从"9" -> "0"
                _dao_lines_assortment.updateTypeForNewLines(key, instance.getUpdatedBy());
            }
            // 如果是定版调达表
            if (1 == instance.getBillType()) {
                // 取得提前组料单
                MrpHeaderEntity _prior_instance = _dao.fetchPriorMrpByStyleNo(instance.getStyleNo(), instance.getMoHeaderId());
                // 如果有提前组料单，则用提前组料的搭配类型进行设置相应的材料
                if (_prior_instance != null) {
                    _dao_lines_assortment.updateTypeByPriorMrp(key, _prior_instance.getHeaderId(), instance.getBomHeaderId(), instance.getUpdatedBy());
                    // 还有一个搭配尺码的更新问题
                    _dao_lines_assortment.insertAssormentSizeByPriorMrp(key, _prior_instance.getHeaderId(), instance.getUpdatedBy());
                    // 为了进行下一步搭配计算，首先清空搭配结果
                    _dao_lines_result.deleteByHeaderId(key);
                    // 计算四种搭配类型的物料需求数据
                    _dao_lines_assortment.batchAssort(key, instance.getMoHeaderId(), instance.getStyleNo(), (short) 0);
                    _dao_lines_assortment.batchAssort(key, instance.getMoHeaderId(), instance.getStyleNo(), (short) 1);
                    _dao_lines_assortment.batchAssort(key, instance.getMoHeaderId(), instance.getStyleNo(), (short) 2);
                    _dao_lines_assortment.batchAssort(key, instance.getMoHeaderId(), instance.getStyleNo(), (short) 3);
                    // 通过提前组料单更新定版调达的提前组料数、规格、备注，并重新计算补给数
                    _dao_lines_result.updateByPriorMrpLines(key, _prior_instance.getHeaderId(), instance.getUpdatedBy());
                    // 清空用来引入尺码搭配数据的提前组料搭配明细ID字段内容
                    _dao_lines_assortment.cleanPriorMrpAssortmentLinesId(key);
                }
            }

            // 审计日志
            if (0 == instance.getBillType()) {
                writeAuditLog(instance.getUpdatedBy(), "技术管理→物料需求计划",
                        "合同号：" + instance.getContractNo() + "　款号：" + instance.getStyleNo(), "增加提前组料单（主辅料）");
            }
            if (1 == instance.getBillType()) {
                writeAuditLog(instance.getUpdatedBy(), "技术管理→物料需求计划",
                        "合同号：" + instance.getContractNo() + "　款号：" + instance.getStyleNo(), "增加定版调达表（主辅料）");
            }
            if (2 == instance.getBillType()) {
                writeAuditLog(instance.getUpdatedBy(), "技术管理→物料需求计划",
                        "合同号：" + instance.getContractNo() + "　款号：" + instance.getStyleNo(), "增加（辅资材）");
            }
        }

        return fetchByHeaderId(key, instance.getUpdatedBy(), instance.getWorkFlowId());
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public Integer update(MrpHeaderEntity instance) throws Exception {
        Integer rowsAffected = _dao.update(instance);

        // 审计日志
        if (rowsAffected > 0) {
            if (0 == instance.getBillType()) {
                writeAuditLog(instance.getUpdatedBy(), "技术管理→物料需求计划",
                        "合同号：" + instance.getContractNo() + "　款号：" + instance.getStyleNo(), "更新提前组料单（主辅料）");
            }
            if (1 == instance.getBillType()) {
                writeAuditLog(instance.getUpdatedBy(), "技术管理→物料需求计划",
                        "合同号：" + instance.getContractNo() + "　款号：" + instance.getStyleNo(), "更新定版调达表（主辅料）");
            }
            if (2 == instance.getBillType()) {
                writeAuditLog(instance.getUpdatedBy(), "技术管理→物料需求计划",
                        "合同号：" + instance.getContractNo() + "　款号：" + instance.getStyleNo(), "更新（辅资材）");
            }
        }

        return rowsAffected;
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public Map<String, Object> delete(Map<String, Object> criterion) throws Exception {
        // 删除
        Integer rowsAffected = _dao.delete(MapUtils.getLong(criterion, "HeaderId"));
        // 审计日志
        if (rowsAffected > 0) {
            if ("0".equals(MapUtils.getString(criterion, "BillType"))) {
                writeAuditLog(MapUtils.getLong(criterion, "DeletedBy"), "技术管理→物料需求计划",
                        "合同号：" + MapUtils.getString(criterion, "DeletedContractNo") + "　款号：" + MapUtils.getString(criterion, "DeletedStyleNo"),
                        "删除提前组料（主辅料）");
            }
            if ("1".equals(MapUtils.getString(criterion, "BillType"))) {
                writeAuditLog(MapUtils.getLong(criterion, "DeletedBy"), "技术管理→物料需求计划",
                        "合同号：" + MapUtils.getString(criterion, "DeletedContractNo") + "　款号：" + MapUtils.getString(criterion, "DeletedStyleNo"),
                        "删除定版调达（主辅料）");
            }
            if ("2".equals(MapUtils.getString(criterion, "BillType"))) {
                writeAuditLog(MapUtils.getLong(criterion, "DeletedBy"), "技术管理→物料需求计划",
                        "合同号：" + MapUtils.getString(criterion, "DeletedContractNo") + "　款号：" + MapUtils.getString(criterion, "DeletedStyleNo"),
                        "删除（辅资材）");
            }
        }

        return fetchForPage(criterion);
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public Map<String, Object> doCheck(Long headerId, Long workFlowId, Short nodeOrder, Long checkedBy, Short isCheckCurrentNode) throws Exception {
        _dao.doCheck(headerId, workFlowId, nodeOrder, checkedBy, isCheckCurrentNode);

        Map<String, Object> _result = new HashMap();
        MrpHeaderEntity instance = _dao.fetchByKey(headerId, checkedBy, workFlowId);
        _result.put("HeaderEntity", instance);
        // 取得搭配明细（计算用单耗明细）
        _result.put("AssortmentLinesList", _dao_lines_assortment.fetchByHeaderId(headerId));
        // 取得计算用单耗明细用成品色
        _result.put("ProductColourNode", _dao_lines_bom_product_colour.fetchByHeaderKey(instance.getBomHeaderId()));
        // 取得材料用量明细
        _result.put("MrpLinesList", _dao_lines_result.fetchByHeaderId(headerId));

        return _result;
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Transactional
    @Override
    public Map<String, Object> doUnCheck(Long headerId, Long workFlowId, Short nodeOrder, Long checkedBy) throws Exception {
        _dao.doUnCheck(headerId, nodeOrder, checkedBy);

        Map<String, Object> _result = new HashMap();
        MrpHeaderEntity instance = _dao.fetchByKey(headerId, checkedBy, workFlowId);
        _result.put("HeaderEntity", instance);
        // 取得搭配明细（计算用单耗明细）
        _result.put("AssortmentLinesList", _dao_lines_assortment.fetchByHeaderId(headerId));
        // 取得计算用单耗明细用成品色
        _result.put("ProductColourNode", _dao_lines_bom_product_colour.fetchByHeaderKey(instance.getBomHeaderId()));
        // 取得材料用量明细
        _result.put("MrpLinesList", _dao_lines_result.fetchByHeaderId(headerId));

        return _result;
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Override
    @Transactional
    public Map<String, Object> fetchPrintPreviewData(Map<String, Object> criterion) throws Exception {
        Map<String, Object> _result = new HashMap();

        _result.put("HeaderEntity", _dao.fetchByKey(MapUtils.getLong(criterion, "HeaderId"),
                MapUtils.getLong(criterion, "CurrentUserId"),
                MapUtils.getLong(criterion, "WorkFlowId"))
        );
        // 取得对应生产指示书的该款号尺码信息
        _result.put("ProductSizeList", _dao_mo_lines_size.fetchProductSize(
                MapUtils.getLong(criterion, "MoHeaderId"),
                null,
                MapUtils.getLong(criterion, "ProductId"))
        );
        _result.put("ProductQuantity", _dao_mo_lines.fetchProductQuantityPerColour(
                MapUtils.getLong(criterion, "MoHeaderId"),
                MapUtils.getLong(criterion, "ProductColourId"))
        );
        // 取得物料需求计划明细
        _result.put("MrpLinesList", _dao_lines_result.fetchPrintDataByProductColour(
                MapUtils.getLong(criterion, "HeaderId"),
                MapUtils.getLong(criterion, "MoHeaderId"),
                MapUtils.getLong(criterion, "ProductId"),
                MapUtils.getLong(criterion, "ProductColourId"))
        );

        return _result;
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Override
    @Transactional
    public Map<String, Object> fetchPrintDataWithMoFormat(Long headerId, Long moHeaderId, Long productId, Long bomHeaderId) throws Exception {
        Map<String, Object> _result = new HashMap();

        // 取得生产指示书产品信息（带尺码）
        _result.put("SuitStyleNo", _dao_mo_lines_styleno.fetchSuitStyleNoByHeaderId(moHeaderId));
        _result.put("ProductInfo", _dao_mo_lines.fetchProductInfoWithSize(moHeaderId, productId));
        // 取得生产指示书明细颜色、数量
        _result.put("MoLinesList", _dao_mo_lines.fetchProductQuantityWithColour(moHeaderId));

        // 取得计算用单耗明细用成品色
        _result.put("ProductColourNode", _dao_lines_bom_product_colour.fetchByHeaderKey(bomHeaderId));
        _result.put("MrpLinesList", _dao_lines_result.fetchPrintDataWithMoFormat(headerId));

        return _result;
    }

    /**
     * {@inheritDoc}
     *
     * @throws java.lang.Exception
     */
    @Override
    @Transactional
    public Map<String, Object> setPoOverFlag(Long headerId, Long currentUserId, Long workFlowId, Boolean poOverFlag) throws Exception {
        Map<String, Object> _result = new HashMap();

        Integer rowsAffected = _dao.setPoOverFlag(headerId, poOverFlag);
        if (rowsAffected > 0) {
            // 如果设置为采购未完成，那么需要返回当前的状态，以利于设置画面元素
            if (!poOverFlag) {
                _result.put("HeaderEntity", _dao.fetchByKey(headerId, currentUserId, workFlowId));
            }
        }
        return _result;
    }
}
